package org.collection.immutable;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

/**
 * 不可变对象有很多优点，包括：
	当对象被不可信的库调用时，不可变形式是安全的；
	不可变对象被多个线程调用时，不存在竞态条件问题
	不可变集合不需要考虑变化，因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率（分析和测试细节）；
	不可变对象因为有固定不变，可以作为常量来安全使用。
创建对象的不可变拷贝是一项很好的防御性编程技巧。Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本。
 *
 */
public class ImmutableTest {

	public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
			"red",
			"orange",
			"yellow",
			"green",
			"blue",
			"purple");
	
	public static void main(String[] args) {
		Set<String> strSet = new HashSet<>();
		strSet.add("1");
		strSet.add("2");
		
		// 创建strSet的不可变版本
		Set<String> copySet = ImmutableSet.copyOf(strSet);
		//copySet.add("3"); // 抛出异常， java.lang.UnsupportedOperationException
		printCollection(copySet);
	
		strSet.add("3");
		printCollection(strSet);
		
		// 使用不可变集合
		//1.copyOf
		Set<String> secondCopySet = ImmutableSet.copyOf(copySet);
		printCollection(secondCopySet);
		
		//2.of
		Set<String> thirdCopySet = ImmutableSet.of("a", "b", "c", "d");
		printCollection(thirdCopySet);
		
		//3.Builder工具
		ImmutableSet<String> fourCopySet = ImmutableSet.<String>builder().add("X").add("Y").add("Z").build();
		printCollection(fourCopySet);
		
		// 智能地将Set转换为List
		ImmutableList<String> immutableList = ImmutableList.copyOf(fourCopySet);
		printCollection(immutableList);
	}

	private static <T> void printCollection(Collection<T> collectionObj) {
		System.out.println("-----------");
		for (T item : collectionObj) {
			System.out.print(item.toString() + " ");
		}
		System.out.println();
	}
}
